package com.atguigu.gmall.activity.receiver;

import com.atguigu.gmall.activity.mapper.SeckillGoodsMapper;
import com.atguigu.gmall.activity.service.SeckillGoodsService;
import com.atguigu.gmall.common.constant.MqConst;
import com.atguigu.gmall.common.constant.RedisConst;
import com.atguigu.gmall.common.util.DateUtil;
import com.atguigu.gmall.model.activity.SeckillGoods;
import com.atguigu.gmall.model.activity.UserRecode;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.rabbitmq.client.Channel;
import lombok.SneakyThrows;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.sleuth.SpanName;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;

@Component
@SuppressWarnings("all")
public class ActivityReceiver {


    @Autowired
    private SeckillGoodsMapper seckillGoodsMapper;
    @Autowired
    private SeckillGoodsService seckillGoodsService;

    @Autowired
    private RedisTemplate redisTemplate;


    /**
     * 秒杀结束，清除数据
     * @param message
     * @param channel
     */
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = MqConst.QUEUE_TASK_18,durable = "true",autoDelete = "false"),
            exchange =@Exchange(value = MqConst.EXCHANGE_DIRECT_TASK),
            key = {MqConst.ROUTING_TASK_18}
    ))
    @SneakyThrows
    public void clearToRedis(Message message, Channel channel){

        try {
            //查询当天秒杀结束的商品
            QueryWrapper<SeckillGoods> queryWrapper=new QueryWrapper<>();
            queryWrapper.eq("status",1);
            queryWrapper.le("end_time",new Date());

            //执行查询
            List<SeckillGoods> seckillGoodsList = seckillGoodsMapper.selectList(queryWrapper);
            //遍历处理
            //判断
            if(!CollectionUtils.isEmpty(seckillGoodsList)){
                for (SeckillGoods seckillGoods : seckillGoodsList) {

                    //删除商品信息对象
                    redisTemplate.boundHashOps(RedisConst.SECKILL_GOODS).delete(seckillGoods.getSkuId().toString());

                    //删除库存
                    redisTemplate.delete(RedisConst.SECKILL_STOCK_PREFIX+seckillGoods.getSkuId().toString());

                    //秒杀商品设置状态位2
                    //                seckillGoods.setStatus("2");
                    //                seckillGoodsMapper.updateById(seckillGoods);

                }

                //删除临时订单
                redisTemplate.delete(RedisConst.SECKILL_ORDERS);
                //删除持久订单
                redisTemplate.delete(RedisConst.SECKILL_ORDERS_USERS);

                //设置状态
                SeckillGoods seckillGoods=new SeckillGoods();
                seckillGoods.setStatus("2");
                seckillGoodsMapper.update(seckillGoods,queryWrapper);





            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);


    }
    /**
     * 更新库存
     * @param userRecode
     * @param message
     * @param channel
     */
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = MqConst.QUEUE_SECKILL_STOCK,durable = "true",autoDelete = "false"),
            exchange =@Exchange(value = MqConst.EXCHANGE_DIRECT_SECKILL_STOCK) ,
            key = {MqConst.ROUTING_SECKILL_STOCK}
    ))
    @SneakyThrows
    public void seckillStock(String goodsId,Message message,Channel channel){

        try {
            //判断
            if(!StringUtils.isEmpty(goodsId)){


                seckillGoodsService.updateStock(goodsId);


            }
        } catch (Exception e) {
            //记录日志，通知处理。。。。
            e.printStackTrace();
        }
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
    }





    /**
     * 监听秒杀下单
     * @param userRecode
     * @param message
     * @param channel
     */
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = MqConst.QUEUE_SECKILL_USER,durable = "true",autoDelete = "false"),
            exchange =@Exchange(value = MqConst.EXCHANGE_DIRECT_SECKILL_USER) ,
            key = {MqConst.ROUTING_SECKILL_USER}
    ))
    @SneakyThrows
    public void seckillOrder(UserRecode userRecode,Message message,Channel channel){

        try {
            //判断
            if(userRecode!=null){

                seckillGoodsService.seckillOrder(userRecode.getUserId(),userRecode.getSkuId());

            }
        } catch (Exception e) {
            //记录日志，通知处理。。。。
            e.printStackTrace();
        }


        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
    }

    /**
     * 秒杀商品预热
     * @param message
     * @param channel
     */
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = MqConst.QUEUE_TASK_1,durable = "true",autoDelete = "false"),
            exchange =@Exchange(value = MqConst.EXCHANGE_DIRECT_TASK),
            key = {MqConst.ROUTING_TASK_1}
    ))
    @SneakyThrows
    public void importToRedis(Message message, Channel channel){


        System.out.println("我收到了消息，我开始预热。。。。");

        //查询符合当天秒杀商品数据
        QueryWrapper<SeckillGoods> queryWrapper=new QueryWrapper<>();
        //审核通过 status  0表示未审核  1表示审核通过  2秒杀结束
        queryWrapper.eq("status","1");
        //有库存
        queryWrapper.gt("stock_count",0);
        //时间
        queryWrapper.eq("date_format(start_time,'%Y-%m-%d')", DateUtil.formatDate(new Date()));
        //执行查询
        List<SeckillGoods> goodsList = seckillGoodsMapper.selectList(queryWrapper);

        //判断
        if(!CollectionUtils.isEmpty(goodsList)){
            for (SeckillGoods seckillGoods : goodsList) {

                //查询是否存在
                BoundHashOperations<String,String,SeckillGoods> boundHashOps = redisTemplate.boundHashOps(RedisConst.SECKILL_GOODS);
                //判断
                if(boundHashOps.hasKey(seckillGoods.getSkuId().toString())){
                    return ;
                }
                //存储秒杀商品基本信息
                boundHashOps.put(seckillGoods.getSkuId().toString(),seckillGoods);

                //获取库存
                Integer stockCount = seckillGoods.getStockCount();
                //存储商品库存skuId
                for (Integer i = 0; i < stockCount; i++) {

                    //存储
                    redisTemplate.opsForList().leftPush(RedisConst.SECKILL_STOCK_PREFIX+seckillGoods.getSkuId(),seckillGoods.getSkuId().toString());

                }


                //同步状态位 24:1
                redisTemplate.convertAndSend("seckillpush",seckillGoods.getSkuId()+":1");

            }




        }




        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
    }
}
